﻿using Sys.Core.Models.Queries;
using Sys.Core.Models.VO;
using Sys.Core.Providers;
using MiniFox.Components;
using MiniFox.Data.EntityFramework;
using MiniFox.Infrastructure;

namespace Sys.Data
{
    [AutoResolve]
    public class OnlineProvider : EntityDataProvider<PlatformDbContext>, IOnlineProvider
    {
        public ResultObject<IEnumerable<AuthCodeVo>> AuthCodeQuery(PagedQueryObject<AuthQuery> request)
        {
            var list = (from t in this.CurrentDbContext.SysAuthCode
                        join p in this.CurrentDbContext.SysPassportToken on t.TicketId equals p.TicketId
                        join u in this.CurrentDbContext.SysUser on p.UserId equals u.UserId
                        select new
                        {
                            t.TicketId,
                            t.AppId,
                            t.Code,
                            t.Context,
                            t.Scope,
                            t.CreateTime,
                            t.ExpireTime,
                            u.UserId,
                            u.DisplayName,
                            u.LoginName,
                            u.SecEmail,
                            u.Cellphone,
                            p.ClientIp,
                        });
            var result = this.PagedQueryExecute(list, request);
            var response = result.GetResultObject(item => new AuthCodeVo
            {
                TicketID = item.TicketId,
                DisplayName = item.DisplayName,
                LoginName = item.LoginName,
                Cellphone = item.Cellphone,
                SecEmail = item.SecEmail,
                AppID = item.AppId,
                Code = item.Code,
                CreateTime = item.CreateTime,
                ExpireTime = item.ExpireTime,
                Context = item.Context,
                Scope = item.Scope,
                ClientIP = item.ClientIp
            });
            return response;
        }

        public ResultObject<IEnumerable<AuthTokenVo>> AuthTokenQuery(PagedQueryObject<AuthQuery> request)
        {
            var list = (from t in this.CurrentDbContext.SysAuthToken
                        join p in this.CurrentDbContext.SysPassportToken on t.TicketId equals p.TicketId
                        join u in this.CurrentDbContext.SysUser on p.UserId equals u.UserId
                        select new
                        {
                            t.TicketId,
                            t.AppId,
                            t.RenewToken,
                            t.AccessToken,
                            t.Context,
                            t.Scope,
                            u.UserId,
                            u.DisplayName,
                            u.LoginName,
                            u.SecEmail,
                            u.Cellphone,
                            p.ClientIp,
                            t.CreateTime,
                            t.AccessExpireTime,
                            t.RenewExpireTime
                        });
            var result = this.PagedQueryExecute(list, request);
            var response = result.GetResultObject(item => new AuthTokenVo
            {
                TicketID = item.TicketId,
                DisplayName = item.DisplayName,
                LoginName = item.LoginName,
                Cellphone = item.Cellphone,
                SecEmail = item.SecEmail,
                AppID = item.AppId,
                RefreshToken = item.RenewToken,
                AccessToken = item.AccessToken,
                AccessExpiredTime = item.AccessExpireTime,
                CreateTime = item.CreateTime,
                ExpireTime = item.RenewExpireTime,
                Context = item.Context,
                Scope = item.Scope,
                ClientIP = item.ClientIp
            });
            return response;
        }

        public void Logoff(params string[] ticketId)
        {
            var tokens = this.CurrentDbContext.SysPassportToken.Where(t => ticketId.Contains(t.TicketId)).ToArray();
            this.Delete(tokens);
        }

        public ResultObject<IEnumerable<OnlineVo>> OnlineQuery(PagedQueryObject<OnlineQuery> request)
        {
            var list = (from t in this.CurrentDbContext.SysPassportToken
                        join u in this.CurrentDbContext.SysUser on t.UserId equals u.UserId
                        select new
                        {
                            t.TicketId,
                            u.DisplayName,
                            u.LoginName,
                            u.Cellphone,
                            u.SecEmail,
                            t.CreateTime,
                            t.RenewTime,
                            t.ExpireTime,
                            t.ClientIp
                        });
            var result = this.PagedQueryExecute(list, request);
            var response = result.GetResultObject(item => new OnlineVo
            {
                TicketID = item.TicketId,
                DisplayName = item.DisplayName,
                LoginName = item.LoginName,
                Cellphone = item.Cellphone,
                SecEmail = item.SecEmail,
                CreateTime = item.CreateTime,
                RenewTime = item.RenewTime,
                ExpireTime = item.ExpireTime,
                ClientIP = item.ClientIp,
            });
            return response;
        }

        public void RemoveAuthCode(string appId, string ticketId, string code)
        {
            var item = this.CurrentDbContext.SysAuthCode.SingleOrDefault(t => t.AppId == appId && t.TicketId == ticketId && t.Code == code);
            this.Delete(item);
        }

        public void RemoveAuthToken(string appId, string ticketId)
        {
            var item = this.CurrentDbContext.SysAuthToken.SingleOrDefault(t => t.AppId == appId && t.TicketId == ticketId);
            this.Delete(item);
        }

        public ResultObject<IEnumerable<SigninLogVo>> SignInLogQuery(PagedQueryObject<SignInQuery> request)
        {
            var query = (from s in this.CurrentDbContext.SysSignLog
                         join u in this.CurrentDbContext.SysUser on s.UserId equals u.UserId
                         select new
                         {
                             s.TicketId,
                             u.DisplayName,
                             s.LoginName,
                             s.SecEmail,
                             s.Cellphone,
                             s.SignOnTime,
                             s.SignOffTime,
                             s.IpAddress
                         });
            var result = this.PagedQueryExecute(query, request);
            var response = result.GetResultObject(item => new SigninLogVo
            {
                TicketID = item.TicketId,
                DisplayName = item.DisplayName,
                LoginName = item.LoginName,
                SecEmail = item.SecEmail,
                Cellphone = item.Cellphone,
                SignInTime = item.SignOnTime,
                SignOutTime = item.SignOffTime,
                IPAddress = item.IpAddress,
            });
            return response;
        }
    }
}
